package com.kyhd.audio.controller.filter;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

import org.springframework.core.annotation.Order;

import com.google.common.collect.Maps;
import com.kyhd.audio.util.RequestContextLog;
import com.kyhd.audio.util.ThreadLocalUtil;

import lombok.extern.slf4j.Slf4j;

@Order(1)
@Slf4j
@WebFilter(filterName = "logFilter1", urlPatterns = {
        "/audio/*"
        })
public class LogFilter implements Filter {
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;

		RequestContextLog reqContext = new RequestContextLog();
		String uri = request.getRequestURI();
		Enumeration<?> pNames = request.getParameterNames();
		Map<String, String> params = Maps.newHashMap();
	    StringBuilder parameters = new StringBuilder();
		while (pNames.hasMoreElements()) {
			String pName = (String) pNames.nextElement();
			String pValue = request.getParameter(pName);
	        parameters.append(pName + ":" + pValue + " || ");
			params.put(pName, pValue);
		}
		
		Enumeration<?> hNames = request.getHeaderNames();
	    StringBuilder headers = new StringBuilder();
		while (hNames.hasMoreElements()) {
			String hName = (String) hNames.nextElement();
			String hValue = request.getHeader(hName);
			headers.append(hName + ":" + hValue + " || ");
			params.put(hName, hValue);
			if("User-Agent".equalsIgnoreCase(hName)) {
				reqContext.setUa(hValue);
			}
			if("Referer".equalsIgnoreCase(hName)) {
				reqContext.setReferer(hValue);
			}
			
			try {
				if("X-Forwarded-For".equalsIgnoreCase(hName)) {
					reqContext.setIp(hValue.split(",")[0]);
				}
			} catch (Exception e) {
				if("X-Real-IP".equalsIgnoreCase(hName)) {
					reqContext.setIp(hValue);
				}
			}
		}
		
		log.info("URI:{"+uri+"}, "+"Parameter:{"+parameters.toString()+"}, "+"Headers:{"+headers.toString()+"}");
		
		ThreadLocalUtil.requestCtxTL.set(reqContext);
		long start = System.currentTimeMillis();
        filterChain.doFilter(servletRequest, servletResponse);
        long end = System.currentTimeMillis();
        log.info("URI:{} completed response time:{}",uri,end-start);
		ThreadLocalUtil.requestCtxTL.remove();
	}
	
	@Override
	public void destroy() {
		
	}

}
